﻿using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MathNetDemo.Startup
{
    internal class Stage_01_MatrixVector
    {
        public static void Run()
        {

            // create a dense matrix with 3 rows and 4 columns
            // filled with random numbers sampled from the standard distribution
            Matrix<double> m = Matrix<double>.Build.Random(3, 4);
            // create a dense zero-vector of length 10
            Vector<double> v = Vector<double>.Build.Dense(10);

            Console.WriteLine("Matrix 3x4 Random : \n" + m);
            Console.WriteLine("Vector 10 Zero : \n" + v);

            //---------------------------------------------------
            //预先建立生成器
            var MatrixBuilder = Matrix<double>.Build;
            var VectorBuilder = Vector<double>.Build;
            // build the same as above
            var mm = MatrixBuilder.Random(3, 4);
            var vv = VectorBuilder.Dense(10);
            //各种建立方式
            // 3x4 dense matrix filled with zeros
            MatrixBuilder.Dense(3, 4);
            // 3x4 dense matrix filled with 1.0.
            MatrixBuilder.Dense(3, 4, 1.0);
            // 3x4 dense matrix where each field is initialized using a function
            MatrixBuilder.Dense(3, 4, (i, j) => 100 * i + j);
            // 3x4 square dense matrix with each diagonal value set to 2.0
            MatrixBuilder.DenseDiagonal(3, 4, 2.0);
            // 3x3 dense identity matrix
            MatrixBuilder.DenseIdentity(3);
            // 3x4 dense random matrix sampled from a Gamma distribution
            MatrixBuilder.Random(3, 4, new Gamma(1.0, 5.0));
            //---------------------------------------------------
            //凡是带有 of 关键字的方法 都是拷贝  否则为绑定
            // Copy of an existing matrix (can also be sparse or diagonal)
            Matrix<double> matRandom = Matrix<double>.Build.Random(3, 4);
            MatrixBuilder.DenseOfMatrix(matRandom);

            // Directly bind to an existing column-major array without copying (note: no "Of")
            double[] arrayx = { 1, 2, 4, 8, 1, 5, 4, 1, 5, 7, 7, 8 };
            MatrixBuilder.Dense(3, 4, arrayx);
          
            // From a 2D-array
            double[,] array2d = {{ 1.0, 2.0 },
               { 3.0, 4.0 }};
            MatrixBuilder.DenseOfArray(array2d);

            // From an enumerable of values and their coordinates
            Tuple<int, int, double>[] tuple = { Tuple.Create(0, 0, 2.0), Tuple.Create(0, 1, -3.0) };
            MatrixBuilder.DenseOfIndexed(3, 4, tuple);

            // From an enumerable in column major order (column by column) //列优先
            double[] arrayCol = { 1.0, 2.0, 3.0, 4.0 };
            MatrixBuilder.DenseOfColumnMajor(2, 2, arrayCol);

            // From an enumerable of enumerable-columns (optional with explicit size) 每个列表都为子列
            IEnumerable<IEnumerable<double>> x =
                new List<List<double>>(){
                    new List<double>() {4.14,8.18,42.3,7.72 },
                    new List<double>() {6.14,8.38,32.3,2.97  },
                    new List<double>() {4.14,4.18,18.3,2.76  },
                };
            MatrixBuilder.DenseOfColumns(x); 

            // From a params-array of array-columns (or an enumerable of them)
            MatrixBuilder.DenseOfColumnArrays(new[] { 2.0, 3.0 }, new[] { 4.0, 5.0 });

            // From a params-array of column vectors (or an enumerable of them)
            MatrixBuilder.DenseOfColumnVectors(VectorBuilder.Random(3), VectorBuilder.Random(3));

            // Equivalent variants also for rows or diagonals:
            MatrixBuilder.DenseOfRowArrays(new[] { 2.0, 3.0 }, new[] { 4.0, 5.0 });
            MatrixBuilder.DenseOfDiagonalArray(new[] { 2.0, 3.0, 4.0 });

            // if you already have existing matrices and want to concatenate them 已有矩阵拼装
            Matrix<double> existMat1 = Matrix<double>.Build.Random(2, 3);
            Matrix<double> existMat2 = Matrix<double>.Build.Random(2, 3);
            Matrix<double>[,] matd = { 
                { existMat1, existMat2 },
                { existMat2, existMat1 } };
            MatrixBuilder.DenseOfMatrixArray(matd);

            


        }


    }
}
